package ginparse

import (
	"Hypnos-Soundcore/components/config"
	"Hypnos-Soundcore/components/encrypt"
	"Hypnos-Soundcore/constants"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/pquerna/ffjson/ffjson"
	"net/http"
	"reflect"
)

// 初始化数据结构
func initializeStruct(t reflect.Type, v reflect.Value) {
	for i := 0; i < v.NumField(); i++ {
		f := v.Field(i)
		ft := t.Field(i)
		switch ft.Type.Kind() {
		case reflect.Map:
			f.Set(reflect.MakeMap(ft.Type))
		case reflect.Slice:
			f.Set(reflect.MakeSlice(ft.Type, 0, 0))
		case reflect.Chan:
			f.Set(reflect.MakeChan(ft.Type, 0))
		case reflect.Struct:
			initializeStruct(ft.Type, f)
		case reflect.Ptr:
			fv := reflect.New(ft.Type.Elem())
			initializeStruct(ft.Type.Elem(), fv.Elem())
			f.Set(fv)
		default:
		}
	}
}

// 设置数据结构的默认值
func setDefaultValue(obj interface{}) {
	parseFields, parseErr := parseObjFields(obj, true, true)
	if parseErr == nil && len(parseFields) > 0 {
		valueOf := reflect.ValueOf(obj)
		if valueOf.Kind() == reflect.Ptr {
			valueOf = valueOf.Elem()
		}
		for _, field := range parseFields {
			if len(field.Default) > 0 {
				valueOf.FieldByName(field.NameOrg).Set(reflect.ValueOf(field.GetDefaultValueAny()))
			}
		}
	}
}

// NewCustomStruct 动态创建任意数据结构，返回的是指针
func NewCustomStruct(in interface{}) interface{} {
	t := reflect.TypeOf(in)
	v := reflect.New(t)
	initializeStruct(t, v.Elem())
	setDefaultValue(v.Interface())
	return v.Interface()
}

// ResponseJSON 请求返回json数据
func ResponseJSON(c *gin.Context, code int, obj interface{}) {
	if config.IsAesEncrypt() {
		var bodyData string
		ranNum, cipher := encrypt.BuildCipher()
		data, err := ffjson.Marshal(obj)
		if err == nil {
			bodyData, err = encrypt.AesEncrypt(cipher, string(data))
		}
		if err == nil {
			c.Header(constants.HeaderRandomNumber, fmt.Sprintf("%d", ranNum))
			c.String(code, bodyData)
		} else {
			c.AbortWithStatus(http.StatusInternalServerError)
		}
	} else {
		c.JSON(code, obj)
	}
}
